//
//  YYStarScoreView.m
//  YYStarScorePorject
//
//  Created by 蓓蕾 on 2021/11/26.
//

#import "YYStarScoreView.h"

@implementation YYStarConfig

-(id)init
{
    if (self = [super init]) {
        //titleView
        _titleFont = [UIFont systemFontOfSize:15];
        _titleTextColor = [UIColor blackColor];
        _titleBetweenStarOfSpace = 0;
        _titleBgColor = [UIColor clearColor];
        
        //infoView
        _infoFont = [UIFont systemFontOfSize:12];
        _infoTextColor = [UIColor blackColor];
        _infoBetweenStarOfSpace = 0;
        _infoBgColor = [UIColor clearColor];
        
        _normalImage = @"non_star";
        _selectImage = @"light_star";
        _numberOfStars = 5;
        _currentScore = 0.0;
        _spacingBetweenStars = 0.0;
        _starSize = CGSizeMake(24, 24);
        _starSizeOfWidth = 24;
        _isAnimation = YES;
        _allowClickScore = YES;
        _allowSlideScore = YES;
    }
    
    return self;
}

@end



@interface YYStarScoreView (){
    /** 5颗黄色星的父view，用来裁剪5颗黄色星 */
    UIView *_clipView;
}

@property (nonatomic, strong) YYStarConfig *config;

//@property (nonatomic, assign) CGFloat currentStarRate;

@property (nonatomic, strong) UIView *titleBgView;

@property (nonatomic, strong) UILabel *titleView;

@property (nonatomic, strong) UIView *starBgView;

@property (nonatomic, strong) UIView *infoBgView;

@property (nonatomic, strong) UILabel *infoView;

@property (nonatomic, assign) CGSize starSize;

@property (nonatomic, assign) CGFloat starSizeOfWidth;

@property (nonatomic, assign) BOOL haveTitleView;
@property (nonatomic, assign) BOOL haveInfoView;

@end

@implementation YYStarScoreView

#pragma mark - 构造方法
- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        _starSize = (_config.starSize.width > 0 || _config.starSize.height > 0) ? _config.starSize : CGSizeMake(24, 24);
        _starSizeOfWidth = _config.starSizeOfWidth > 0 ? _config.starSizeOfWidth : 24;
        _allowClickScore = _config ? _config.allowClickScore : YES;
        _allowSlideScore = _config ? _config.allowSlideScore : YES;
        
        
        [self setUpUI];
    }
    return self;
}

-(id)initWithFrame:(CGRect)frame withConfig:(YYStarConfig *)config
{
    _config = config;
    _isAnimation = config.isAnimation;
    _style = config.style;
    return [self initWithFrame:frame];
}

-(id)initWithFrame:(CGRect)frame withResultBlock:(YYStarRateDidSelectStarBlock)block
{
    _didSelectStarBlock = block;
    return [self initWithFrame:frame];
}

-(id)initWithFrame:(CGRect)frame withConfig:(YYStarConfig *)config withResultBlock:(YYStarRateDidSelectStarBlock)block
{
    _config = config;
    _isAnimation = config.isAnimation;
    _style = config.style;
    _didSelectStarBlock = block;
    return [self initWithFrame:frame];
}

-(id)initWithConfig:(YYStarConfig *)config
{
    _config = config;
    _isAnimation = config.isAnimation;
    _style = config.style;
    return [self initWithFrame:CGRectZero];
}

-(id)initWithResultBlock:(YYStarRateDidSelectStarBlock)block
{
    _didSelectStarBlock = block;
    return [self initWithFrame:CGRectZero];
}

-(id)initWithConfig:(YYStarConfig *)config withResultBlock:(YYStarRateDidSelectStarBlock)block
{
    _config = config;
    _isAnimation = config.isAnimation;
    _style = config.style;
    _didSelectStarBlock = block;
    return [self initWithFrame:CGRectZero];
}

#pragma mark - UI搭建
- (void)setUpUI{
    
    if (!([self isBlankString:_config.titleString] && [self isBlankString:_config.titleAttributedString.string])) {
        _haveTitleView = YES;
        CGFloat right = _config.titleBetweenStarOfSpace;
        _titleBgView = [[UIView alloc] init];
        [self addSubview:_titleBgView];
        [_titleBgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(self.mas_left).mas_offset(0);
            make.bottom.mas_equalTo(self.mas_bottom).mas_offset(0);
            make.top.mas_equalTo(self.mas_top).mas_offset(0);
        }];
        _titleView = [[UILabel alloc] init];
        [_titleBgView addSubview:_titleView];
        if (![self isBlankString:_config.titleString]) {
            _titleView.text = _config.titleString;
        }
        if (![self isBlankString:_config.titleAttributedString.string]) {
            _titleView.attributedText = _config.titleAttributedString;
        }
        _titleView.font = _config.titleFont;
        _titleView.textColor = _config.titleTextColor;
        _titleView.backgroundColor = _config.titleBgColor;
        [_titleView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(_titleBgView.mas_left).mas_offset(0);
            make.right.mas_lessThanOrEqualTo(_titleBgView.mas_right).mas_offset(-right);
            make.centerY.mas_equalTo(_titleBgView.mas_centerY).mas_offset(0);
        }];
    }
    
    _starBgView = [[UIView alloc] init];
    [self addSubview:_starBgView];
    if (_titleBgView) {
        [_starBgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(_titleBgView.mas_right).mas_offset(0);
            make.top.mas_equalTo(self.mas_top).mas_offset(0);
            make.bottom.mas_equalTo(self.mas_bottom).mas_offset(0);
        }];
    }
    else
    {
        [_starBgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(self.mas_left).mas_offset(0);
            make.top.mas_equalTo(self.mas_top).mas_offset(0);
            make.bottom.mas_equalTo(self.mas_bottom).mas_offset(0);
        }];
    }
    
    UIView *lastView = nil;
    NSInteger numberOfStars = _config.numberOfStars > 0 ? _config.numberOfStars : 5;
    CGFloat spacingBetweenStars = _config.spacingBetweenStars > 0 ? _config.spacingBetweenStars : 0.0;
    for (int i = 0; i < numberOfStars; i ++) {
        UIImageView *grayImageView = [[UIImageView alloc]init];
        [_starBgView addSubview:grayImageView];
        grayImageView.image = [UIImage imageNamed:[self isBlankString:_config.normalImage] ? @"non_star" : _config.normalImage];
        [grayImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_equalTo(_starBgView);
            make.size.mas_offset(_starSize);
            if (lastView) {
                make.left.mas_equalTo(lastView.mas_right).offset(spacingBetweenStars);
            }else{
                make.left.mas_equalTo(_starBgView);
            }
        }];
        lastView = grayImageView;
    }
    
    [_starBgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo(lastView);
    }];
    
    if (!([self isBlankString:_config.infoString] && [self isBlankString:_config.infoAttributedString.string])) {
        _haveInfoView = YES;
        CGFloat left = _config.infoBetweenStarOfSpace;
        _infoBgView = [[UIView alloc] init];
        [self addSubview:_infoBgView];
        [_infoBgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(_starBgView.mas_right).mas_offset(left);
            make.bottom.mas_equalTo(self.mas_bottom).mas_offset(0);
            make.top.mas_equalTo(self.mas_top).mas_offset(0);
        }];
        _infoView = [[UILabel alloc] init];
        [_infoBgView addSubview:_infoView];
        if (![self isBlankString:_config.infoString]) {
            _infoView.text = _config.infoString;
        }
        if (![self isBlankString:_config.infoAttributedString.string]) {
            _infoView.attributedText = _config.infoAttributedString;
        }
        _infoView.font = _config.infoFont;
        _infoView.textColor = _config.infoTextColor;
        _infoView.backgroundColor = _config.infoBgColor;
        [_infoView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(_infoBgView.mas_left).mas_offset(0);
            make.right.mas_lessThanOrEqualTo(_infoBgView.mas_right).mas_offset(0);
            make.centerY.mas_equalTo(_infoBgView.mas_centerY).mas_offset(0);
        }];
    }
    
    if (_infoBgView) {
        [self mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(_infoBgView);
        }];
    }
    else
    {
        [self mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(_starBgView);
        }];
    }
    // 裁剪黄色星的view
    _clipView = [[UIView alloc]init];
    [_starBgView addSubview:_clipView];
    _clipView.clipsToBounds = YES; // 裁剪开启
    [_clipView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(_starBgView);
        make.left.mas_equalTo(_starBgView);
        make.bottom.mas_equalTo(_starBgView);
        make.width.mas_equalTo(_starBgView).multipliedBy(0.5);
    }];

    // 创建5个黄色星
    UIView *lastYellowView = nil;
    for (int i = 0; i < numberOfStars; i ++) {
        UIImageView *yellowImageView = [[UIImageView alloc]init];;
        [_clipView addSubview:yellowImageView];
        yellowImageView.image = [UIImage imageNamed:([self isBlankString:_config.selectImage] ? @"light_star" : _config.selectImage)];
        [yellowImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_equalTo(_clipView);
//            make.bottom.mas_equalTo(self);
            make.size.mas_equalTo(_starSize);
            if (lastYellowView) {
                make.left.mas_equalTo(lastYellowView.mas_right).mas_offset(spacingBetweenStars);
            }else{
                make.left.mas_equalTo(_clipView);
            }
        }];
        lastYellowView = yellowImageView;
    }
    
    self.currentScore = _config.currentScore;
}

#pragma - 设置星级
/** 设置星级 */
- (void)setCurrentScore:(CGFloat)currentScore{
    NSInteger numberOfStars = _config.numberOfStars > 0 ? _config.numberOfStars : 5;
    currentScore = currentScore < 0 ? 0 : currentScore;
    currentScore = currentScore > numberOfStars ? numberOfStars : currentScore;
    _currentScore = currentScore;
    CGFloat spacingBetweenStars = _config.spacingBetweenStars > 0 ? _config.spacingBetweenStars : 0.0;
    
    NSInteger index = (NSInteger)floor(currentScore);
    CGFloat w = (_starSizeOfWidth + spacingBetweenStars) * index + (currentScore - index) * _starSizeOfWidth;
    
    [_clipView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(_starBgView);
        make.left.mas_equalTo(_starBgView);
        make.bottom.mas_equalTo(_starBgView);
        make.width.mas_equalTo(w);
    }];
    
    if (self.didSelectStarBlock) {
        self.didSelectStarBlock(self, currentScore);
    }
    
    if ([self.delegate respondsToSelector:@selector(starRateView:didSelecteStarAtStarRate:)]) {
        [self.delegate starRateView:self didSelecteStarAtStarRate:currentScore];
    }
}

#pragma mark - event
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    if (_allowClickScore) {
        UITouch *touch = [touches anyObject];
        UIView *view = touch.view;
//        if (view == self || [view isMemberOfClass:[YYStarImageView class]]) {
            CGPoint point = [touch locationInView:view];
            [self setupScoreWithOffsetX:point.x];
            NSLog(@"point = %@",NSStringFromCGPoint(point));
//        }
    }
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if (_allowSlideScore) {
        UITouch *touch = [touches anyObject];
        UIView *view = touch.view;
//        if (view == self || [view isMemberOfClass:[YYStarImageView class]]) {
            CGPoint point = [touch locationInView:view];
            [self setupScoreWithOffsetX:point.x];
//        }
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
//    NSLog(@"touchesEnded");
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
//    NSLog(@"touchesCancelled");
}

#pragma mark - 根据offsetx计算分数
- (void)setupScoreWithOffsetX:(CGFloat)offsetX {
    CGFloat spacingBetweenStars = _config.spacingBetweenStars > 0 ? _config.spacingBetweenStars : 0.0;
    NSInteger index = offsetX / (_starSizeOfWidth + spacingBetweenStars);
    CGFloat mathOffsetX =  (index + 1) * _starSizeOfWidth + index * spacingBetweenStars;
    CGFloat score = (offsetX - index * spacingBetweenStars)/_starSizeOfWidth;
    if (offsetX > mathOffsetX) {
        score = index + 1;
    }
    self.currentScore = [self currentStarRateWithScore:score];
}

- (CGFloat)currentStarRateWithScore:(CGFloat)score {
    
    switch (self.style) {
        case YYStarRateViewStyleWholeStar: //全星
            score = ceil(score);
            break;
        case YYStarRateViewStyleHalfStar: //半星
            score = round(score) > score ? round(score) : (score < (ceil(score)-0.5) ? (ceil(score)-0.5) : ceil(score));
            break;
        case YYStarRateViewStyleIncompleteStar: //不完整星
            score = score;
            break;
    }
    return score;
}

#pragma mark - 检查字符串是否为空 YES:为空  NO:不为空
- (BOOL)isBlankString:(NSString *)string
{
    if (![string isKindOfClass:[NSString class]]) {
        return YES;
    } else if (string == nil) {
        return YES;
    } else if ([string isKindOfClass:[NSNull class]]) {
        return YES;
    } else if ([string isEqualToString:@"null"]) {
        return YES;
    } else if ([string isEqualToString:@"(null)"]) {
        return YES;
    } else if ([string isEqualToString:@"<null>"]) {
        return YES;
    } else if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
        return YES;
    } else {
        return NO;
    }
}

-(void)setTitleString:(NSString *)titleString
{
    _titleString = titleString;
    _titleView.text = titleString;
}

-(void)setTitleAttributedString:(NSAttributedString *)titleAttributedString
{
    _titleAttributedString = titleAttributedString;
    _titleView.attributedText = titleAttributedString;
}

-(void)setTitleTextColor:(UIColor *)titleTextColor
{
    _titleTextColor = titleTextColor;
    _titleView.textColor = titleTextColor;
}

-(void)setTitleBgColor:(UIColor *)titleBgColor
{
    _titleBgColor = titleBgColor;
    _titleView.backgroundColor = titleBgColor;
}

-(void)setTitleFont:(UIFont *)titleFont
{
    _titleFont = titleFont;
    _titleView.font = titleFont;
}

-(void)setTitleBetweenStarOfSpace:(CGFloat)titleBetweenStarOfSpace
{
    _titleBetweenStarOfSpace = titleBetweenStarOfSpace;
    [_titleBgView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo(_titleView.mas_right).mas_offset(titleBetweenStarOfSpace);
    }];
}
#pragma mark - infoView 设置
-(void)setInfoString:(NSString *)infoString
{
    _infoString = infoString;
    _infoView.text = infoString;
}

-(void)setInfoAttributedString:(NSAttributedString *)infoAttributedString
{
    _infoAttributedString = infoAttributedString;
    _infoView.attributedText = infoAttributedString;
}

-(void)setInfoTextColor:(UIColor *)infoTextColor
{
    _infoTextColor = infoTextColor;
    _infoView.textColor = infoTextColor;
}

-(void)setInfoBgColor:(UIColor *)infoBgColor
{
    _infoBgColor = infoBgColor;
    _infoView.backgroundColor = infoBgColor;
}

-(void)setInfoFont:(UIFont *)infoFont
{
    _infoFont = infoFont;
    _infoView.font = infoFont;
}

-(void)setInfoBetweenStarOfSpace:(CGFloat)infoBetweenStarOfSpace
{
    _infoBetweenStarOfSpace = infoBetweenStarOfSpace;
    [_infoBgView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo(_infoView.mas_right).mas_offset(infoBetweenStarOfSpace);
    }];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
